﻿#region Copyright & licence

// This file is part of Refix.
// 
// Refix is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
// 
// Refix is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public
// License along with Refix.  If not, see <http://www.gnu.org/licenses/>.
// 
// Copyright (C) 2010-11 David Musgrove and others.

#endregion

using System;
using System.Configuration;
using System.IO;
using System.Reflection;

using NUnit.Framework;

using Refix.Core.Commands;
using Refix.Core.Repository;

namespace Refix.Core.Tests.Commands
{
    [TestFixture]
    public class RegisterUnregisterTest
    {
        private DirectoryInfo _solutionRootDirectory;

        [TestFixtureSetUp]
        public void TextFixtureSetUp()
        {
            var fileInfo = new FileInfo(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath);
            _solutionRootDirectory = fileInfo.Directory.Parent.Parent.Parent;
            string repoPath = Path.Combine(_solutionRootDirectory.FullName, ".testrefixrepo");
            ConfigurationManager.AppSettings.Set("Refix.Repository.Local", repoPath);
            ConfigurationManager.AppSettings.Set("Refix.Repository.Remote", string.Empty);
            Environment.SetEnvironmentVariable(EnvironmentVariables.RefixLocalRepository, null,
                                               EnvironmentVariableTarget.Process);
            Environment.SetEnvironmentVariable(EnvironmentVariables.RefixRemoteRepository, null,
                                               EnvironmentVariableTarget.Process);
        }

        [Test]
        public void Register_Unregister_Adds_And_Removes_Component()
        {
            var localRepository = new LocalRepository();
            Directory.SetCurrentDirectory(_solutionRootDirectory.FullName);

            Component componentBefore = localRepository.GetComponent("Refix.Test.A", false);
            Assert.AreEqual(4, componentBefore.Versions.Count, "Refix.Test.A had wrong number of versions before test.");

            const string NEW_ASSEMBLY_LOCATION = "TestFiles\\Refix.Test.A.dll";
            Command register = new CommandWithOptions(new[] {"reg", "-f", NEW_ASSEMBLY_LOCATION}).Command;

            register.Execute();

            Component componentDuring = localRepository.GetComponent("Refix.Test.A", false);
            Assert.AreEqual(5, componentDuring.Versions.Count, "Refix.Test.A had wrong number of versions during test.");
            Assert.True(
                File.Exists(Path.Combine(_solutionRootDirectory.FullName,
                                         ".testrefixrepo\\Refix\\Test\\A\\0.1.0.5\\Refix.Test.A.dll")),
                "DLL file not copied into repository.");
            Assert.True(
                File.Exists(Path.Combine(_solutionRootDirectory.FullName,
                                         ".testrefixrepo\\Refix\\Test\\A\\0.1.0.5\\Refix.Test.A.pdb")),
                "PDB file not copied into repository.");
            Assert.True(
                File.Exists(Path.Combine(_solutionRootDirectory.FullName,
                                         ".testrefixrepo\\Refix\\Test\\A\\0.1.0.5\\Refix.Test.A.xml")),
                "XML file not copied into repository.");
            Assert.True(
                File.Exists(Path.Combine(_solutionRootDirectory.FullName,
                                         ".testrefixrepo\\Refix\\Test\\A\\0.1.0.5\\Refix.Test.A.dll.config")),
                "Config file not copied into repository.");

            Command unregister = new CommandWithOptions(new[] {"unreg", "-f", "Refix.Test.A", "0.1.0.5"}).Command;
            unregister.Execute();

            Component componentAfter = localRepository.GetComponent("Refix.Test.A", false);
            Assert.AreEqual(4, componentAfter.Versions.Count, "Refix.Test.A had wrong number of versions after test.");
        }

        [Test]
        public void Register_Unregister_Executable_Adds_And_Removes_Component()
        {
            var localRepository = new LocalRepository();
            Directory.SetCurrentDirectory(_solutionRootDirectory.FullName);

            const string NEW_ASSEMBLY_LOCATION = "Refix\\rfx.exe";
            string version =
                Assembly.ReflectionOnlyLoadFrom(Path.Combine(_solutionRootDirectory.FullName, NEW_ASSEMBLY_LOCATION)).
                    GetName().Version.ToString();

            Component componentBefore = localRepository.GetComponent("rfx.exe", false);
            Assert.IsNull(componentBefore, "rfx.exe found before test.");

            Command register = new CommandWithOptions(new[] { "reg", "-f", NEW_ASSEMBLY_LOCATION }).Command;

            register.Execute();

            Component componentDuring = localRepository.GetComponent("rfx.exe", false);
            Assert.AreEqual(1, componentDuring.Versions.Count, "rfx.exe had wrong number of versions during test.");
            Assert.True(
                File.Exists(Path.Combine(_solutionRootDirectory.FullName,
                                         ".testrefixrepo\\rfx\\exe\\" + version + "\\rfx.exe")),
                "EXE file not copied into repository.");

            Command unregister = new CommandWithOptions(new[] { "unreg", "-f", "rfx.exe", version }).Command;
            unregister.Execute();

            Component componentAfter = localRepository.GetComponent("rfx.exe", false);
            Assert.IsNull(componentAfter, "rfx.exe found after test.");
        }

        [Test]
        public void Register_With_Extra_Includes_Extra_File()
        {
            Directory.SetCurrentDirectory(_solutionRootDirectory.FullName);

            const string NEW_ASSEMBLY_LOCATION = "TestFiles\\Refix.Test.A.dll";
            Command register = new CommandWithOptions(new[] { "reg", "-fx", "TestFiles\\lic*.txt", NEW_ASSEMBLY_LOCATION }).Command;

            register.Execute();

            Assert.True(
                File.Exists(Path.Combine(_solutionRootDirectory.FullName,
                                         ".testrefixrepo\\Refix\\Test\\A\\0.1.0.5\\licence.txt")),
                "Licence file not copied into repository.");

            Command unregister = new CommandWithOptions(new[] { "unreg", "-f", "Refix.Test.A", "0.1.0.5" }).Command;
            unregister.Execute();
        }
    }
}